package com.zh.common.net

import com.blankj.utilcode.util.LogUtils
import com.zh.common.BuildConfig
import com.zh.common.net.http.LocalCookieJar
import com.zh.common.net.http.RequestIntercept
import com.zh.config.ZjConfig
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrl
import okhttp3.Interceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import retrofit2.Retrofit
import retrofit2.converter.gson.GsonConverterFactory
import java.util.concurrent.ConcurrentHashMap
import java.util.concurrent.TimeUnit

/**
 * 网络请求发起的基层调用
 */
class RetrofitManager private constructor() {

    companion object {
        //超时时间
        private const val TOME_OUT = 60

        //多个域名存储请求
        private val serviceMap: ConcurrentHashMap<String, in Any> = ConcurrentHashMap()

        private val interceptors = mutableListOf<Interceptor>()

        val instance: RetrofitManager by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
            interceptors.clear()
            interceptors += HttpLoggingInterceptor().apply {
                level =
                    if (BuildConfig.DEBUG) HttpLoggingInterceptor.Level.BODY else HttpLoggingInterceptor.Level.NONE
            }
            interceptors += RequestIntercept()
            RetrofitManager()
        }

        /**
         * 获取发起Retrofit实列
         * @param clazz 网路请求的 Interface 类
         * @param hostUrl 域名, 默认ZjConfig.base_url，需要修改传入新的域名（新的每次都传）
         */
        fun <T : Any> apiService(clazz: Class<T>, hostUrl: String = ZjConfig.base_url): T {
            val key = "${clazz.name}_$hostUrl"
            val value: T
            if (serviceMap.containsKey(key)) { //拿取已有实列
                value = serviceMap[key] as T
            } else { //没有直接添加
                value = instance.mRetrofit(hostUrl.toHttpUrl()).create(clazz)
                serviceMap[key] = value
            }
            return value
        }
    }

    /**
     * 创建 OkHttpClient
     */
    private val mOkHttpClient by lazy(LazyThreadSafetyMode.SYNCHRONIZED) {
        val build = OkHttpClient.Builder().apply {
            callTimeout(TOME_OUT.toLong(), TimeUnit.SECONDS)
            connectTimeout(TOME_OUT.toLong(), TimeUnit.SECONDS)
            readTimeout(TOME_OUT.toLong(), TimeUnit.SECONDS)
            writeTimeout(TOME_OUT.toLong(), TimeUnit.SECONDS)
            cookieJar(LocalCookieJar())
            interceptors().addAll(interceptors)
        }
        build.build()
    }

    /**
     * 创建 Retrofit
     */
    private fun mRetrofit(url: HttpUrl) = Retrofit.Builder()
        .baseUrl(url) //域名
        .client(mOkHttpClient) //设置okhttp
        .addConverterFactory(GsonConverterFactory.create()) //使用Gson
        .build()
}